﻿using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UIWindow.Domains;
using UIWindow.Lucifer;
using UIWindow.Models;
using UIWindow.Models.S7NET;

namespace UIWindow.DeviceCommunications
{
    public class CommS7 : ICommunication
    {
        private bool _isconnect;
        public bool IsConnect { get { return _isconnect; } }
        public List<byte> ByteCache { get; set; }
        private Plc _plc = null;
        public event CustomDelegates.DropAlarm DropAlarms;
        private string _address;
        private object _obj = new object();
        public CommS7(string address)
        {
            _address = address;
            _plc = new Plc(CpuType.S71500, address, 0, 1);
        }

        public void Close() => _plc.Close();

        public bool Connect()
        {
            try
            {
                _plc.Open();
                _isconnect = true;
                return _plc.IsConnected;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void Read(CancellationTokenSource tokenSource) { }

        public byte[] Read() => new byte[0];

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <typeparam name="T">需要读取的对象</typeparam>
        /// <param name="protocol">使用S7ParamModel对象传递数据</param>
        /// <returns></returns>
        public T ReadWrite<T>(IProtocol protocol) where T : class, new()
        {
            lock (_obj)
            {
                try
                {
                    S7ParamModel model = protocol as S7ParamModel;
                    return _plc.ReadClass<T>(GlobalStart.DBReadNumber, model.Address);
                }
                catch (Exception ex)
                {
                    _isconnect = false;
                    DropAlarms(_address, 9600, 1, ex.Message);
                    return new T();
                }
            }
        }
        public void SetTimeout(int time)
        {
        }
        public void Write(byte[] bytes)
        {
        }

        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="protocol">使用S7ParamModel对象传递数据</param>
        public bool Write(IProtocol protocol)
        {
            lock (_obj)
            {
                try
                {

                    S7ParamModel model = protocol as S7ParamModel;
                    if (model.IsBytes) _plc.WriteBytes(DataType.DataBlock, GlobalStart.DBWriteNumber, model.Address, model.Value);
                    else _plc.WriteBit(DataType.DataBlock, GlobalStart.DBWriteNumber, model.Address, model.BitAddress, model.TF);
                    return true;
                }
                catch (Exception ex)
                {
                    _isconnect = false;
                    DropAlarms(_address, 9600, 1, ex.Message);
                    return false;
                }
            }
        }
    }
}
